﻿using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using MathematicallySafe.HeadCounter.Data;
using MathematicallySafe.HeadCounter.Data.Models;
using MathematicallySafe.Utilities;
using StructureMap;

namespace MathematicallySafe.HeadCounter.Services.Publishers
{
    public class Publisher : BackgroundWorker, IPublishingService
    {
        private static readonly IHeadCounterService HeadCounterService = ObjectFactory.GetInstance<IHeadCounterService>();
        private static readonly UserOptions UserOptions = HeadCounterService.UserOptions;

        public Publisher()
        {
            WorkerReportsProgress = true;
            DoWork += PublishWebsite;
        }

        public void RunPublishingServiceAsync()
        {
            if (!IsBusy)
            {
                ProgressChanged += PublishingProgressChanged;
                RunWorkerCompleted += PublishingRunWorkerCompleted;

                RunWorkerAsync();
            }
        }

        private void PublishWebsite(object sender, DoWorkEventArgs e)
        {
            ReportProgress(0, new[] {"Connecting to website " + UserOptions.FTPDomain, ""});

            var ftp = new SimpleFTPClient(UserOptions.FTPDomain,
                                          new NetworkCredential(UserOptions.FTPUserName, UserOptions.FTPPassword));
            var files = Directory.GetFiles(Constants.HtmlDirectory);
            var newUri = new Uri("ftp://" + ftp.HostId + UserOptions.FTPPath);

            double step = 100.0/files.Count();
            double progress = 0.0;
            int n = 0;
            foreach (string file in files)
            {
                string fileName = Path.GetFileName(file);

                progress += step;
                ReportProgress((int) progress, new[] {"Connected to " + ftp.HostId, "Uploading " + fileName});

                n++;
                ftp.UploadFile(file, newUri);
            }

            ReportProgress(98, new[] {"Connected to " + ftp.HostId, "Uploading Data backup"});

            if (File.Exists(Constants.MainArchivePathName))
            {
                ftp.UploadFile(Constants.MainArchivePathName, newUri);
            }

            ReportProgress(100, new[] {"Upload Complete", ""});
        }

        public bool IsWorking()
        {
            return IsBusy;
        }

        public event EventHandler<RunWorkerCompletedEventArgs> PublishingServiceCompleted;
        public event EventHandler<ProgressChangedEventArgs> PublishingServiceProgressChanged;

        void PublishingProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (PublishingServiceProgressChanged != null)
            {
                PublishingServiceProgressChanged(this as IPublishingService, e);
            }
        }

        void PublishingRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (PublishingServiceCompleted != null)
            {
                PublishingServiceCompleted(this as IPublishingService, e);
            }

            ProgressChanged -= PublishingProgressChanged;
            RunWorkerCompleted -= PublishingRunWorkerCompleted;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            DoWork -= PublishWebsite;
        }
    }
}


